<template>
  <div
      class="t-box"
      :class="[
            type === 'textarea' ? 't-textarea' : 't-input',
            {
              'is-disabled': inputDisabled,
              't-input--prefix': prefixIcon || $slots.prefix,
              't-input--suffix': getSuffixVisible,
            }
        ]"
  >
    <!--        input-->
    <template v-if="type !== 'textarea'">
      <!--        前置 icon-->
      <span
          v-if="prefixIcon || $slots.prefix"
          class="t-input-position t-input-prefix"
      >
          <slot name="prefix"></slot>
          <i
              v-if="prefixIcon"
              :class="prefixIcon"
              class="t-input__icon"
          ></i>
        </span>
      <input
          ref="input"
          class="t-input__inner"
          :type="showPassword ? (passwordVisible ? 'text' : 'password') : type"
          v-bind="$attrs"
          :disabled="inputDisabled"
          :readonly="readOnly"
          v-on="inputListeners"
      >
      <!--        后置 icon-->
      <span
          v-if="getSuffixVisible"
          class="t-input-position t-input-suffix"
      >
          <template v-if="!showPasswordVisible">
            <slot name="suffix"></slot>
            <i
                v-if="suffixIcon"
                :class="suffixIcon"
                class="t-input__icon"
            ></i>
          </template>
        <!--          密码显示隐藏部分-->
          <i
              v-if="showPasswordVisible"
              :class="passwordVisible ? 't-icon-view' : 't-icon-not-view'"
              class="t-input__icon t-input__icon-click"
              @click="handlePasswordVisible"
          ></i>
        </span>
    </template>
    <!--        textarea-->
    <template v-else>
        <textarea
            ref="textarea"
            name=""
            id=""
            cols="30"
            rows="10"
        ></textarea>
    </template>

    <div>
      {{  }}
    </div>
  </div>
</template>

<script>
export default {
  inheritAttrs: false,
  name: "tInput",
  props: {
    // 确定 输入框的类型
    type: {
      type: String,
      default: 'text',
    },
    // 前置 icon
    prefixIcon: {
      type: String,
      default: '',
    },
    // 后置 icon
    suffixIcon: {
      type: String,
      default: '',
    },
    // 显示密码。通过这个来代表是否要显示或隐藏密码的icon
    showPassword: {
      type: Boolean,
      default: false,
    },
    // disable
    inputDisabled: {
      type: Boolean,
      default: false,
    },
    // 只读
    readOnly: {
      type: Boolean,
      default: false,
    }
  },
  data() {
    return {
      passwordVisible: false, // 密码是否可见
      isComposing: false, // 判断是否使用的中文输入法进行的输入。如果是中文输入法，那么就不会input提交。这样不会出现英文验证情况。
    }
  },
  computed: {
    // 是否显示 密码显示隐藏的 icon
    showPasswordVisible() {
      return this.showPassword &&
          !this.inputDisabled &&
          !this.readOnly
    },
    // 是否存在 后置icon
    getSuffixVisible() {
      return this.suffixIcon ||
          this.$slots.suffix ||
          this.showPassword
    },
    // input 输入框的监听事件的覆盖
    inputListeners: function () {
      // `Object.assign` 将所有的对象合并为一个新对象
      return Object.assign({},
          // 我们从父级添加所有的监听器
          this.$listeners,
          // 然后我们添加自定义监听器，
          // 或覆写一些监听器的行为
          {
            // 这里确保组件配合 `v-model` 的工作
            input: this.handleInput,
            compositionstart: this.handleCompositionstart,
            compositionend: this.handleCompositionend,
          }
      )
    }
  },
  methods: {
    // 获取到真正的输入框的 dom
    getInput() {
      return this.$refs.input || this.$refs.textarea
    },
    // 聚焦输入框
    focus() {
      this.getInput().focus()
    },
    // 密码显示隐藏的点击
    handlePasswordVisible() {
      this.passwordVisible = !this.passwordVisible
      this.$nextTick(() => {
        this.focus()
      })
    },
    // input 事件的监听
    handleInput(event) {
      // 处于中文输入的状态，return
      if (this.isComposing) return
      this.$emit('input', event.target.value)
    },
    // 中文输入监听的开始
    handleCompositionstart(event) {
      this.isComposing = true
      this.$emit('compositionstart', event)
    },
    // 中文输入监听的结束
    handleCompositionend(event) {
      if (this.isComposing) {
        this.isComposing = false
        this.inputListeners.input(event)
      }
      this.$emit('compositionend', event)
    }
  },
  mounted() {
  },
}
</script>

<style scoped lang="scss" src="@/style/input/index.scss"></style>
